#include <memory>

#include "tcpserver.hpp"
#include "Protocol.hpp"
#include "calculator.hpp"

Calculator gcal;

using cal_fun = std::function<Response(const Request &req)>;

class Parse
{
public:
    Parse(cal_fun c) : _cal(c)
    {
    }
    std::string Entry(std::string &package)
    {
        // 1. 判断报文的完整性
        std::string message;
        std::string respstr;
        while (Decode(package, &message))
        {
            if (message.empty())
                break;
            std::cout << "########################" << std::endl;
            std::cout << "message:" << message << std::endl;
            std::cout << "########################" << std::endl;

            // 2. 反序列化
            Request req;
            if (!req.Deserialization(message))
                break;
            std::cout << "########################" << std::endl;
            std::cout << "req.x:" << req.X() << std::endl;
            std::cout << "req.y:" << req.Y() << std::endl;
            std::cout << "req.oper:" << req.Oper() << std::endl;
            std::cout << "########################" << std::endl;
            // 3. 计算
            Response resp = _cal(req);

            // 4. 序列化
            std::string res;
            resp.Serialization(res);

            // 5. 添加长度报头
            Encode(res);

            // 6. 拼接应答
            respstr += res;
        }
        return respstr;
    }

private:
    cal_fun _cal;
};

////////////////////////////////////////////////////////////////////////////////

int main()
{
    Calculator mycal;
    Parse myparse([&mycal](const Request &req)
                  { return mycal.Execute(req); });

    std::unique_ptr<Tcpserver> Tcp = std::make_unique<Tcpserver>([&myparse](std::string &package)
                                                                 { return myparse.Entry(package); });

    Tcp->Init();
    Tcp->Start();
    return 0;
}